﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

namespace BadApplePlayer
{
    public partial class Form1 : Form
    {
        public Form1() {
            InitializeComponent();
            pictureBox1.Cursor = pictureBox2.Cursor = pictureBox3.Cursor = Cursors.Hand;
            pictureBox1.BorderStyle = pictureBox2.BorderStyle = pictureBox3.BorderStyle = BorderStyle.FixedSingle;
            pictureBox1.MouseDown += (s, e) => { pictureBox1.Cursor = Cursors.Cross; m_frmRect.Show(); };
            pictureBox1.MouseUp += (s, e) => { pictureBox1.Cursor = Cursors.Hand; m_frmRect.Hide(); };
            pictureBox2.Paint += (s, e) => { using (SolidBrush sb = new SolidBrush(m_clrBack))e.Graphics.FillRectangle(sb, pictureBox2.ClientRectangle); };
            pictureBox3.Paint += (s, e) => { using (SolidBrush sb = new SolidBrush(m_clrLine))e.Graphics.FillRectangle(sb, pictureBox3.ClientRectangle); };
            pictureBox2.Click += new EventHandler(picBoxClr_Click);
            pictureBox3.Click += new EventHandler(picBoxClr_Click);
            trackBar1.ValueChanged += new EventHandler(trackBar1_ValueChanged);
            trackBar2.ValueChanged += new EventHandler(trackBar1_ValueChanged);
            rdBtn_playLine.CheckedChanged += (s, e) => groupBox1.Enabled = rdBtn_playLine.Checked;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
        }

        private void trackBar1_ValueChanged(object sender, EventArgs e) {
            if ((sender as TrackBar) == trackBar1) {
                m_clrBack = Color.FromArgb(trackBar1.Value, m_clrBack);
                pictureBox2.Invalidate();
            } else {
                m_clrLine = Color.FromArgb(trackBar2.Value, m_clrLine);
                pictureBox3.Invalidate();
            }
        }

        private void picBoxClr_Click(object sender, EventArgs e) {
            ColorDialog clrDialog = new ColorDialog();
            if (clrDialog.ShowDialog() == DialogResult.OK) {
                PictureBox picBox = sender as PictureBox;
                if (picBox == pictureBox2)
                    m_clrBack = Color.FromArgb(trackBar1.Value, clrDialog.Color);
                else
                    m_clrLine = Color.FromArgb(trackBar2.Value, clrDialog.Color);
                picBox.Invalidate();
            }
        }

        private int m_nCount;
        private IntPtr m_hWnd;
        private FrmRect m_frmRect;
        private Bitmap m_BmpBack;
        private List<Rectangle> m_lstRectDraw;
        private Color m_clrBack;
        private Color m_clrLine;
        private System.Media.SoundPlayer m_sp;

        private void Form1_Load(object sender, EventArgs e) {
            m_frmRect = new FrmRect();
            m_lstRectDraw = new List<Rectangle>();
            rdBtn_playOriginal.Checked = true;
            pictureBox1.BackColor = Color.Gray;
            m_clrBack = Color.Black;
            m_clrLine = Color.Cyan;
            groupBox1.Enabled = false;
            m_sp = new System.Media.SoundPlayer();
        }

        private void btn_play_Click(object sender, EventArgs e) {
            if (btn_play.Text == "播放") {
                if (m_hWnd == IntPtr.Zero) {
                    MessageBox.Show("目标窗体句柄无效");
                    return;
                }
                if (chbox_bPlayOnSubCtrl.Checked && m_lstRectDraw.Count == 0) {
                    MessageBox.Show("[" + m_hWnd.ToString("X") + "] 的窗体上没有发现子控件");
                    return;
                }

                m_sp.SoundLocation = "Bad_Apple.wav";
                m_sp.Play();
                m_nCount = 0;
                timer1.Enabled = true;
                btn_play.Text = "停止";
            }else{
                m_sp.Stop();
                m_nCount = 0;
                timer1.Enabled = false;
                btn_play.Text = "播放";
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                IntPtr hWnd = Win32.WindowFromPoint(new Win32.POINT() { X = MousePosition.X, Y = MousePosition.Y });
                if (hWnd == m_hWnd) return;
                m_hWnd = hWnd;
                Win32.LPRECT lpRect;
                Win32.POINT lpPoint;
                m_frmRect.ClearSubRect();
                m_lstRectDraw.Clear();
                hWnd = IntPtr.Zero;
                while ((hWnd = Win32.FindWindowEx(m_hWnd, hWnd, null, null)) != IntPtr.Zero) {
                    Win32.GetWindowRect(hWnd, out lpRect);
                    m_frmRect.AddSubRect(lpRect.ToRectangle());

                    lpPoint.X = lpRect.Left; lpPoint.Y = lpRect.Top;
                    Win32.ScreenToClient(m_hWnd, out lpPoint);
                    m_lstRectDraw.Add(new Rectangle(lpPoint.X, lpPoint.Y, lpRect.Width, lpRect.Height));
                }
                Win32.GetWindowRect(m_hWnd, out lpRect);
                if (m_BmpBack != null) m_BmpBack.Dispose();
                m_BmpBack = new Bitmap(lpRect.Width, lpRect.Height);
                using (Graphics g = Graphics.FromImage(m_BmpBack)) {
                    //g.CopyFromScreen(lpRect.Left, lpRect.Top, 0, 0, m_BmpBack.Size);
                    Win32.BitBlt(g.GetHdc(), 0, 0, lpRect.Width, lpRect.Height, Win32.GetDC(m_hWnd), 0, 0, Win32.SRCCOPY);
                }
                m_frmRect.DrawRectangle(lpRect.ToRectangle());
                this.Text = "[" + m_hWnd.ToString("X") + "] 子窗体个数:" + m_lstRectDraw.Count;
            }

        }

        private void timer1_Tick(object sender, EventArgs e) {
            if (m_nCount >= CommonInfo.BadAppleResource.LstImgByte.Count) {
                timer1.Enabled = false;
                btn_play.Text = "播放";
                return;
            }
            if (rdBtn_playLine.Checked)
                PlayLine();
            else
                PlayOriginal();
            return;
            using (Stream s = new MemoryStream(CommonInfo.BadAppleResource.LstImgByte[m_nCount++])) {
                using (Bitmap bmpSrc = new Bitmap(s)) {
                    using (Bitmap bmpReSize = new Bitmap(m_frmRect.RectDraw.Width, m_frmRect.RectDraw.Height)) {
                        using (Graphics g = Graphics.FromImage(bmpReSize)) {
                            g.DrawImage(bmpSrc, new Rectangle(0, 0, bmpReSize.Width, bmpReSize.Height), new Rectangle(0, 0, bmpSrc.Width, bmpSrc.Height), GraphicsUnit.Pixel);
                        }
                        using (Graphics g = Graphics.FromHwnd(m_hWnd)) {
                            using (Bitmap bmp = ImageHelper.MixLineImage(bmpReSize, m_BmpBack, Color.FromArgb(0, 0, 0, 0), Color.Cyan)) {
                                //g.DrawImage(m_BmpBack, 0, 0);
                                g.DrawImage(bmp, 0, 0, m_frmRect.RectDraw.Width, m_frmRect.RectDraw.Height);
                                //for (int i = 0, len = m_lstRectDraw.Count; i < len; i++) {
                                //    g.DrawImage(bmp, m_lstRectDraw[i], m_lstRectDraw[i], GraphicsUnit.Pixel);
                                //    //g.DrawRectangle(Pens.Gray, m_lstRectDraw[i]);
                                //}
                            }
                        }
                    }
                }
            }
        }

        private void PlayOriginal() {
            using (Stream s = new MemoryStream(CommonInfo.BadAppleResource.LstImgByte[m_nCount++])) {
                using (Bitmap bmpSrc = new Bitmap(s)) {
                    using (Bitmap bmpReSize = new Bitmap(m_frmRect.RectDraw.Width, m_frmRect.RectDraw.Height)) {
                        using (Graphics g = Graphics.FromImage(bmpReSize)) {
                            g.DrawImage(bmpSrc, new Rectangle(0, 0, bmpReSize.Width, bmpReSize.Height), new Rectangle(0, 0, bmpSrc.Width, bmpSrc.Height), GraphicsUnit.Pixel);
                        }
                        using (Graphics g = Graphics.FromHwnd(m_hWnd)) {
                            if (chbox_bPlayOnSubCtrl.Checked) {
                                for (int i = 0, len = m_lstRectDraw.Count; i < len; i++)
                                    g.DrawImage(bmpReSize, m_lstRectDraw[i], m_lstRectDraw[i], GraphicsUnit.Pixel);
                            } else
                                g.DrawImage(bmpReSize, 0, 0);
                        }
                    }
                }
            }
        }

        private void PlayLine() {
            using (Stream s = new MemoryStream(CommonInfo.BadAppleResource.LstImgByte[m_nCount++])) {
                using (Bitmap bmpSrc = new Bitmap(s)) {
                    using (Bitmap bmpReSize = ImageHelper.MixLineImage(bmpSrc, m_BmpBack, m_clrBack, m_clrLine)) {
                        //using (Graphics g = Graphics.FromImage(bmpReSize)) {
                        //    g.DrawImage(bmpSrc, new Rectangle(0, 0, bmpReSize.Width, bmpReSize.Height), new Rectangle(0, 0, bmpSrc.Width, bmpSrc.Height), GraphicsUnit.Pixel);
                        //}
                        using (Graphics g = Graphics.FromHwnd(m_hWnd)) {
                            if (chbox_bPlayOnSubCtrl.Checked) {
                                for (int i = 0, len = m_lstRectDraw.Count; i < len; i++)
                                    g.DrawImage(bmpReSize, m_lstRectDraw[i], m_lstRectDraw[i], GraphicsUnit.Pixel);
                            } else
                                g.DrawImage(bmpReSize, 0, 0);
                        }
                    }
                }
            }
        }
    }
}
